import asyncio
import websockets
import threading
import cv2
import pyvirtualcam
import time
import re
import colorsys
import numpy as np

HOST = 'localhost'
PORT = 51746
pattern_RunVideo=r'^run\s+(.*)$'
pattern_StopVideo=r'^stop$'
pattern_AgainVideo=''
pattern_ChangeVideo=''

def GetCommandParam(pattern,command):
    match = re.match(pattern, command)
    if match:
        print("命令格式正确")
        # 提取命令参数
        parameters = command.split()[1:]
        print("命令参数:", parameters)
        return parameters
    else:
        print("命令格式不正确")
        return None
class VideoServer:
    def __init__(self):
        self.ws_server = None
        self.ws = None
        self.is_running = False
        self.is_playing = False
        self.video_path = None
        self.thread = None
        self.cam = None

    def start(self):
        self.ws_server = websockets.serve(self.websocket_handler, HOST, PORT)
        self.is_running = True
        print('视频服务已启动，等待连接...')
        asyncio.get_event_loop().run_until_complete(self.ws_server)
        asyncio.get_event_loop().run_forever()
         

     
    # WebSocket 服务器处理函数
    async def websocket_handler(self,websocket, path):
        print(websocket.remote_address,"连接成功！")
        self.ws = websocket
        try:
            while True:
                # 接收客户端发送的消息
                message = await websocket.recv()
                # 在这里处理接收到的消息
                print("收到命令:", message)
                param = GetCommandParam(pattern_RunVideo,message)
                if(param!=None):
                    self.play_video(param[0])
                if(re.match(pattern_StopVideo,message)):
                    self.stop_video()     
                # 发送消息给客户端
                # response = "Received: " + message
                response = "开始播放"
                await websocket.send(response)
                
        except websockets.exceptions.ConnectionClosed:
            print(websocket.remote_address,"连接已断开！")
            self.stop_video()     

    
     
      

    def play_video(self, video_path):
        if self.is_playing:
            print('已经在播放视频')
            self.stop_video()
            # return

        self.video_path = video_path
        self.is_playing = True

        # 读取源视频的分辨率
        video = cv2.VideoCapture(video_path)
        width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
        height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
        fps = video.get(cv2.CAP_PROP_FPS)
        print(width,height,fps)
        video.release()

        # 创建虚拟摄像头，使用与源视频相同的分辨率
        self.cam = pyvirtualcam.Camera(width=width, height=height, fps=fps)
        self.thread = threading.Thread(target=self.camera_loop)
        self.thread.start()

    def stop_video(self):
        if not self.is_playing:
            print('没有正在播放的视频')
            return
        self.is_playing = False
        self.thread.join()  # 等待 camera_loop 线程结束
        self.cam.close()
        print('视频播放已停止')

    def camera_loop(self):
        video = cv2.VideoCapture(self.video_path)

        while self.is_playing:
            grabbed, frame = video.read()
            if not grabbed:
                self.cam.close()
                print('视频播放结束')
                self.is_playing = False
                # await self.ws.send("播放结束")
                 
                break

            frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            self.cam.send(frame_rgb)
            self.cam.sleep_until_next_frame()

        video.release()
         

# 线程函数，每隔5秒往日志文件写入心跳
def heartbeat():
    print("心跳包启动...")  
    while True:
        try:
            # 在这里写入心跳到日志文件的代码
            with open("heartbeat.log", 'w') as file:
                file.write(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) 
            print("Heartbeat")
            time.sleep(5)
        except:
            print("心跳写入异常！")

# 创建并启动心跳线程
heartbeat = threading.Thread(target=heartbeat)
heartbeat.start()
 
# 启动视频服务
server = VideoServer()
server.start()
